package edu.uiuc.ncsa;

import edu.uiuc.ncsa.commons.NCSAKMLUtilityException;
import edu.uiuc.ncsa.commons.util.FilenameUtils;
import edu.uiuc.ncsa.commons.util.Util;

import java.io.*;

/**
 * @author : Sachith Dhanushka (sachith.dhanushka@gmail.com)
 * @date : Jun 7, 2008 - 11:11:34 PM
 */
public class ShapeFileConverter {

    private String execCommandBase = "ogr2ogr -f KML -t_srs +proj=latlong ";

    public void convert(String source, String destination) throws NCSAKMLUtilityException {

        File[] sourceFiles = null;
        File destDir = null;

        try {
            String basePath = new File(".").getAbsolutePath();
            sourceFiles = edu.uiuc.ncsa.commons.util.Util.getSourceFiles(source, basePath);

            destDir = Util.getDestinationDir(destination, basePath);

            // transform the shape file using ogr2ogr
            transform(sourceFiles, destDir);

        } catch (IOException e) {
            throw new NCSAKMLUtilityException(e);
        } catch (NCSAKMLUtilityException e) {
            throw new NCSAKMLUtilityException(e);
        }

    }

    public void convert(File source, File destination) throws NCSAKMLUtilityException {

        File[] sourceFiles = null;
        File destDir = null;

        try {
            String basePath = new File(".").getAbsolutePath();
            sourceFiles = edu.uiuc.ncsa.commons.util.Util.getSourceFiles(source.getAbsolutePath(), basePath);

            destDir = Util.getDestinationDir(destination.getAbsolutePath(), basePath);

            // transform the shape file using ogr2ogr
            transform(sourceFiles, destDir);

        } catch (IOException e) {
            throw new NCSAKMLUtilityException(e);
        } catch (NCSAKMLUtilityException e) {
            throw new NCSAKMLUtilityException(e);
        }

    }

    private void transform(File[] sourceFiles, File destDir) throws NCSAKMLUtilityException {

        for (File f : sourceFiles) {


            String tempPath = FilenameUtils.concat(destDir.getAbsolutePath(), "output.kml");
            File temp = transform(f.getAbsolutePath(), tempPath);

            // now convert the file to kml 2.2
            File destFile = new File(temp.getParentFile(), "output-2-2.kml");

            Util.convertKML20ToKML22(temp, destFile);

            temp.delete();

        }

    }

    private void convertKML20ToKML22(File sourceFile) {

        File destFile = new File(sourceFile.getParentFile(), "output-2-2.kml");

        try {
            BufferedReader in = new BufferedReader(new FileReader(sourceFile));

            BufferedWriter out = new BufferedWriter(new FileWriter(destFile));


            String str;
            while ((str = in.readLine()) != null) {
                if (str.contains("http://earth.google.com/kml/2.0")) {
                    str = str.replace("xmlns=\"http://earth.google.com/kml/2.0\"", "xmlns=\"http://www.opengis.net/kml/2.2\"");
                }
                out.write(str + "\n");
            }
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public File transform(String sourceFullPath, String destFullPath) throws NCSAKMLUtilityException {

//		String ogr2ogrExec = config.getString(CFG_OGR2OGR_EXEC, );

//		if (execCommandBase == null) {
//			throw new NullPointerException("ogr2ogr execute command not found in teKML.properties file");
//		}

        String cmd = execCommandBase + " " + destFullPath + " " + sourceFullPath;

        File fout = null;
        Process p = null;

        try {
            System.out.println("Executing ogr2ogr with command >>" + cmd + "<<");
            p = Runtime.getRuntime().exec(cmd);

            p.waitFor();  //need to wait so can read file

            fout = new File(destFullPath);
            if (!fout.exists()) {
                throw new IOException("Transformed file not created: " + destFullPath);
            }
            System.out.println("Transformed file created: " + destFullPath);

        } catch (IOException e) {
            throw new NCSAKMLUtilityException(e);
        } catch (InterruptedException e) {
            throw new NCSAKMLUtilityException(e);
        } catch (SecurityException e) {
            throw new NCSAKMLUtilityException(e);
        } catch (NullPointerException e) {
            throw new NCSAKMLUtilityException(e);
        } catch (IllegalArgumentException e) {
            throw new NCSAKMLUtilityException(e);
        } finally {
            p.destroy();
        }

        return fout;
    }

    public static void main(String[] args) {


        if (args.length != 2) {
            printHelp();
            System.exit(-1);
        }

        File sourceShapeFile = new File(args[0]);

        if (!sourceShapeFile.isFile()) {
            printHelp();
            System.exit(-1);
        }


        ShapeFileConverter converter = new ShapeFileConverter();
        File destinationFile = new File(args[1]);

        if (!destinationFile.isDirectory()) {
            destinationFile.mkdir();
        }

        try {
            converter.convert(sourceShapeFile.getAbsolutePath(), destinationFile.getName());
        } catch (NCSAKMLUtilityException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    private static void printHelp() {
        System.out.println("============================================================");
        System.out.println("=                        H E L P                           =");
        System.out.println("============================================================");
        System.out.println("=                                                          =");
        System.out.println("= Two parameters needed to convert the shape file          =");
        System.out.println("= into a kml 2.2 file.                                     =");
        System.out.println("= 1. shape file path                                       =");
        System.out.println("= 2. destination folder                                    =");
        System.out.println("=                                                          =");
        System.out.println("= command : ant -Dsf=<shapeFilePath> -Ddest=<targetFolder> =");
        System.out.println("= (Both parameters are mandatory)                          =");
        System.out.println("============================================================");
    }


}
